<template>
  <div class="guestbook-management">
    <el-card class="box-card">
      <div slot="header" class="card-header">
        <span>留言管理</span>
        <div class="header-actions">
          <el-select v-model="statusFilter" placeholder="状态筛选" @change="handleSearch" clearable style="width: 150px;">
            <el-option label="全部留言" value=""></el-option>
            <el-option label="未回复" value="0"></el-option>
            <el-option label="已回复" value="1"></el-option>
          </el-select>
        </div>
      </div>
      
      <!-- 卡片区域 -->
      <div class="message-cards" v-loading="loading" element-loading-text="加载中..." element-loading-spinner="el-icon-loading" element-loading-background="rgba(255, 255, 255, 0.7)">
        <el-empty v-if="guestbookList.length === 0" description="暂无留言数据"></el-empty>
        
        <el-row :gutter="20">
          <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" v-for="item in sortedGuestbookList" :key="item.gbId" class="card-col">
            <el-card class="message-card" :class="{'replied': item.status === '1'}" shadow="hover">
              <div class="card-top">
                <div class="message-status">
                  <el-tag :type="item.status === '1' ? 'success' : 'warning'" size="small">
                    {{ item.status === '1' ? '已回复' : '未回复' }}
                  </el-tag>
                </div>
                <div class="card-id">#{{ item.gbId }}</div>
              </div>
              
              <div class="card-body">
                <div class="card-title">
                  <i class="el-icon-user"></i>
                  <span class="author-name">{{ item.gbName || '匿名用户' }}</span>
                </div>
                <div class="card-contact" v-if="item.gbPhone || item.gbEmail">
                  <span v-if="item.gbPhone"><i class="el-icon-phone"></i> {{ item.gbPhone }}</span>
                  <span v-if="item.gbEmail"><i class="el-icon-message"></i> {{ item.gbEmail }}</span>
                </div>
                <div class="card-subject" v-if="item.gbTheme">
                  <span class="subject-label">主题：</span>
                  <span class="subject-text">{{ item.gbTheme }}</span>
                </div>
                <div class="card-content">{{ item.gbContent }}</div>
                <div class="card-time">
                  <i class="el-icon-time"></i> {{ formatDate(item.gbTime) }}
                </div>
              </div>
              
              <div class="card-footer">
                <el-tooltip content="回复留言" placement="top" effect="light">
                  <el-button 
                    size="mini" 
                    type="primary" 
                    icon="el-icon-edit" 
                    @click.stop="handleReply(item)"
                  >回复</el-button>
                </el-tooltip>
                <el-tooltip content="查看回复记录" placement="top" effect="light" v-if="item.status === '1'">
                  <el-button 
                    size="mini" 
                    type="success" 
                    icon="el-icon-document" 
                    @click.stop="handleViewReplyHistory(item)"
                  >记录</el-button>
                </el-tooltip>
                <el-tooltip content="删除留言" placement="top" effect="light">
                  <el-button 
                    size="mini" 
                    type="danger" 
                    icon="el-icon-delete" 
                    @click.stop="handleDelete(item)"
                  >删除</el-button>
                </el-tooltip>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </div>
      
      <!-- 分页组件 -->
      <div class="pagination-container">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageNum"
          :page-sizes="[12, 24, 48, 96]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          background
        >
        </el-pagination>
      </div>
    </el-card>

    <!-- 回复对话框 -->
    <el-dialog
      title="回复留言"
      :visible.sync="replyDialogVisible"
      width="600px"
      custom-class="reply-dialog"
      @close="resetReplyForm"
    >
      <div class="message-brief" v-if="currentMessage">
        <div class="message-info-brief">
          <div class="info-row">
            <span class="label">留言人：</span>
            <span class="value">{{ currentMessage.gbName || '匿名用户' }}</span>
          </div>
          <div class="info-row" v-if="currentMessage.gbTheme">
            <span class="label">主题：</span>
            <span class="value">{{ currentMessage.gbTheme }}</span>
          </div>
          <div class="info-row" v-if="currentMessage.gbPhone || currentMessage.gbEmail">
            <span class="label">联系方式：</span>
            <span class="value">
              <template v-if="currentMessage.gbPhone">
                <i class="el-icon-phone"></i> {{ currentMessage.gbPhone }}
              </template>
              <template v-if="currentMessage.gbPhone && currentMessage.gbEmail"> / </template>
              <template v-if="currentMessage.gbEmail">
                <i class="el-icon-message"></i> {{ currentMessage.gbEmail }}
              </template>
            </span>
          </div>
          <div class="info-row">
            <span class="label">留言时间：</span>
            <span class="value">{{ formatDate(currentMessage.gbTime) }}</span>
          </div>
          <div class="info-row message-content-row">
            <span class="label">留言内容：</span>
            <span class="value">{{ currentMessage.gbContent }}</span>
          </div>
        </div>
      </div>
      
      <el-form :model="replyForm" :rules="replyRules" ref="replyForm" label-width="80px" class="reply-form">
        <el-form-item label="回复内容" prop="replyContent">
          <el-input
            type="textarea"
            :rows="6"
            placeholder="请输入回复内容"
            v-model="replyForm.replyContent"
          ></el-input>
        </el-form-item>
      </el-form>
      
      <div slot="footer" class="dialog-footer">
        <el-button @click="replyDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitReply" :loading="submitting">确 定</el-button>
      </div>
    </el-dialog>
    
    <!-- 回复历史记录对话框 -->
    <el-dialog
      title="回复历史记录"
      :visible.sync="replyHistoryDialogVisible"
      width="650px"
      top="8vh"
      custom-class="history-dialog"
    >
      <div class="reply-history" v-loading="historyLoading">
        <div class="history-message" v-if="currentMessage">
          <div class="history-header">
            <span class="history-title">{{ currentMessage.gbName}}</span>
            <span class="history-time">{{ formatDate(currentMessage.gbTime) }}</span>
          </div>
          <div class="history-theme" v-if="currentMessage.gbTheme">
            <span class="theme-label">主题：</span>
            <span class="theme-value">{{ currentMessage.gbTheme }}</span>
          </div>
          <div class="history-content">
            <span class="content-label">留言内容：</span>
            <div class="content-value">{{ currentMessage.gbContent }}</div>
          </div>
        </div>
        
        <el-divider content-position="center">回复记录</el-divider>
        
        <el-empty v-if="replyHistory.length === 0" description="暂无回复记录"></el-empty>
        
        <div class="timeline-container">
          <el-timeline v-if="replyHistory.length > 0">
            <el-timeline-item
              v-for="(reply, index) in replyHistory"
              :key="reply.replyId"
              :timestamp="formatDate(reply.replyTime)"
              :color="getTimelineItemColor(index)"
              size="large"
            >
              <el-card class="reply-history-card" shadow="hover">
                <div class="reply-history-content">{{ reply.replyContent }}</div>
                <div class="reply-history-footer">
                  <span class="reply-user">回复人: {{ reply.replyUser }}</span>
                </div>
              </el-card>
            </el-timeline-item>
          </el-timeline>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import service from '@/utils/request';

export default {
  name: 'GuestbookManagement',
  data() {
    return {
      // 表格数据
      guestbookList: [],
      // 分页相关
      pageNum: 1,
      pageSize: 12,
      total: 0,
      // 状态筛选
      statusFilter: '',
      // 加载状态
      loading: false,
      submitting: false,
      historyLoading: false,
      // 对话框控制
      replyDialogVisible: false,
      replyHistoryDialogVisible: false,
      // 当前选中的留言
      currentMessage: null,
      // 回复记录
      replyHistory: [],
      // 回复表单
      replyForm: {
        replyContent: '',
        gbId: '',
        email: '',
        token: localStorage.getItem('token')
      },
      // 回复表单验证规则
      replyRules: {
        replyContent: [
          { required: true, message: '请输入回复内容', trigger: 'blur' },
          { min: 5, max: 500, message: '回复内容长度在 5 到 500 个字符之间', trigger: 'blur' }
        ]
      }
    };
  },
  filters: {
    // 文本截断过滤器
    ellipsis(value) {
      if (!value) return '';
      if (value.length <= 50) return value;
      return value.slice(0, 50) + '...';
    }
  },
  created() {
    this.fetchGuestbookList();
    window.scrollTo(0, 0);
  },
  computed: {
    // 对留言列表进行排序：未回复的排在前面，然后按时间旧的在前
    sortedGuestbookList() {
      if (!this.guestbookList || this.guestbookList.length === 0) {
        return [];
      }
      
      return [...this.guestbookList].sort((a, b) => {
        // 首先按照回复状态排序（未回复的排在前面）
        if (a.status !== b.status) {
          return a.status === '1' ? 1 : -1;
        }
        
        // 如果回复状态相同，则按照时间从旧到新排序
        const timeA = new Date(a.gbTime).getTime();
        const timeB = new Date(b.gbTime).getTime();
        return timeA - timeB;
      });
    }
  },
  methods: {
    // 获取留言列表
    fetchGuestbookList() {
      this.loading = true;
      service.get('/api/system/guestbook/getList', {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          ...(this.statusFilter !== '' && { status: this.statusFilter })
        }
      }).then(res => {
        if (res.code === 200) {
          console.log(res.data);
          this.guestbookList = res.data.list;
          this.total = res.data.total;
        } else {
          this.$message.error(res.message || '获取留言列表失败');
        }
      }).catch(err => {
        this.$message.error('系统错误，请稍后重试');
        console.error(err);
      }).finally(() => {
        this.loading = false;
      });
    },
    
    // 获取回复历史记录
    fetchReplyHistory(gbId) {
      this.historyLoading = true;
      service.get(`/api/system/guestbook/replyHistory/${gbId}`)
        .then(res => {
          if (res.code === 200) {
            // 按时间从近到远排序
            this.replyHistory = (res.data || []).sort((a, b) => {
              return new Date(b.replyTime).getTime() - new Date(a.replyTime).getTime();
            });
          } else {
            this.$message.error(res.message || '获取回复历史记录失败');
            this.replyHistory = [];
          }
        })
        .catch(err => {
          this.$message.error('系统错误，请稍后重试');
          console.error(err);
          this.replyHistory = [];
        })
        .finally(() => {
          this.historyLoading = false;
        });
    },
    
    // 查看回复历史
    handleViewReplyHistory(row) {
      this.currentMessage = row;
      this.replyHistoryDialogVisible = true;
      this.fetchReplyHistory(row.gbId);
    },
    
    // 获取时间线项目颜色
    getTimelineItemColor(index) {
      const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399'];
      return colors[index % colors.length];
    },
    
    // 搜索
    handleSearch() {
      this.pageNum = 1;
      this.fetchGuestbookList();
    },
    
    // 分页大小改变
    handleSizeChange(size) {
      this.pageSize = size;
      this.fetchGuestbookList();
    },
    
    // 当前页改变
    handleCurrentChange(page) {
      this.pageNum = page;
      this.fetchGuestbookList();
    },
    
    // 回复留言
    handleReply(row) {
      this.currentMessage = row;
      this.replyForm.gbId = row.gbId;
      this.replyForm.email = row.gbEmail;
      this.replyDialogVisible = true;
    },
    
    // 提交回复
    submitReply() {
      this.$refs.replyForm.validate(valid => {
        if (valid) {
          this.submitting = true;
          
          service.post('/api/system/guestbook/reply', this.replyForm)
            .then(res => {
              if (res.code === 200) {
                this.$message.success('回复成功');
                this.replyDialogVisible = false;
                this.fetchGuestbookList();
              } else {
                this.$message.error(res.message || '回复失败');
              }
            })
            .catch(err => {
              this.$message.error('系统错误，请稍后重试');
              console.error(err);
            })
            .finally(() => {
              this.submitting = false;
            });
        }
      });
    },
    
    // 重置回复表单
    resetReplyForm() {
      if (this.$refs.replyForm) {
        this.$refs.replyForm.resetFields();
      }
      this.replyForm.replyContent = '';
      this.replyForm.email = '';
    },
    
    // 删除留言
    handleDelete(row) {
      this.$confirm('确定要删除该留言吗？删除后将无法恢复', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        service.delete(`/api/system/guestbook/delete/${row.gbId}`)
          .then(res => {
            if (res.code === 200) {
              this.$message.success('删除成功');
              this.fetchGuestbookList();
            } else {
              this.$message.error(res.message || '删除失败');
            }
          })
          .catch(err => {
            this.$message.error('系统错误，请稍后重试');
            console.error(err);
          });
      }).catch(() => {
        // 用户取消删除
      });
    },
    
    // 格式化日期
    formatDate(timestamp) {
      if (!timestamp) return '-';
      const date = new Date(timestamp);
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, '0');
      const day = date.getDate().toString().padStart(2, '0');
      const hours = date.getHours().toString().padStart(2, '0');
      const minutes = date.getMinutes().toString().padStart(2, '0');
      const seconds = date.getSeconds().toString().padStart(2, '0');
      
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    }
  }
};
</script>

<style scoped>
.guestbook-management {
  padding: 0;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  align-items: center;
}

/* 卡片样式 */
.message-cards {
  margin-top: 20px;
}

.card-col {
  margin-bottom: 20px;
}

.message-card {
  position: relative;
  transition: all 0.3s;
  height: 100%;
  display: flex;
  flex-direction: column;
   /* border-left: 4px solid #f57905; */
   /* border: 0.03px solid #0f0f0f; */
}

.message-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1) !important;
}

/* .message-card.replied {
  border-left: 4px solid #67c23a;

} */

.card-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.card-id {
  font-size: 12px;
  color: #909399;
}

.card-body {
  flex: 1;
  padding-bottom: 10px;
}

.card-title {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
}

.card-title i {
  margin-right: 5px;
  color: #409EFF;
}

.author-name {
  font-weight: bold;
  font-size: 16px;
}

.card-contact {
  margin-bottom: 10px;
  font-size: 13px;
  color: #606266;
  display: flex;
  flex-direction: column;
}

.card-contact span {
  margin-bottom: 5px;
}

.card-contact i {
  margin-right: 5px;
  color: #909399;
}

.card-subject {
  margin-bottom: 10px;
  font-size: 14px;
}

.subject-label {
  color: #606266;
  font-weight: bold;
}

.card-content {
  background-color: #f9f9f9;
  padding: 10px;
  border-radius: 4px;
  margin-bottom: 10px;
  height: 80px;
  overflow-y: auto;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  word-break: break-all;
  line-height: 1.6;
}

.card-time {
  font-size: 12px;
  color: #909399;
  margin-bottom: 10px;
}

.card-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid #ebeef5;
}

.pagination-container {
  margin-top: 20px;
  text-align: right;
}

/* 回复对话框样式 */
.message-brief {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03);
}

.message-info-brief {
  margin-bottom: 0;
}

.info-row {
  margin-bottom: 15px;
  display: flex;
  align-items: flex-start;
}

.info-row:last-child {
  margin-bottom: 0;
}

.label {
  font-weight: bold;
  width: 100px;
  color: #606266;
}

.value {
  flex: 1;
  word-break: break-all;
}

.message-content-row {
  border-top: 1px dashed #e0e0e0;
  padding-top: 15px;
  margin-top: 15px;
}

.message-content-row .value {
  white-space: pre-wrap;
  line-height: 1.8;
  color: #303133;
  padding: 8px 0;
}

.reply-form {
  margin-top: 20px;
}

.reply-form .el-form-item__label {
  font-weight: bold;
  color: #606266;
}

.reply-form .el-textarea__inner {
  background-color: #fafafa;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 12px 15px;
  font-size: 14px;
  line-height: 1.8;
  transition: all 0.3s;
}

.reply-form .el-textarea__inner:focus {
  background-color: #fff;
  border-color: #409EFF;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.reply-dialog .el-dialog__header {
  padding: 20px;
  border-bottom: 1px solid #ebeef5;
  background-color: #f5f7fa;
}

.reply-dialog .el-dialog__title {
  font-size: 18px;
  color: #303133;
  font-weight: bold;
}

.reply-dialog .el-dialog__body {
  padding: 20px 20px 10px;
}

.reply-dialog .el-dialog__footer {
  padding: 15px 20px 20px;
  border-top: 1px solid #ebeef5;
  background-color: #f5f7fa;
}

/* 回复历史记录样式 */
.reply-history {
  padding: 0 10px;
}

.history-message {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03);
}

.history-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.history-title {
  font-weight: bold;
  color: #303133;
  font-size: 16px;
}

.history-time {
  font-size: 12px;
  color: #909399;
}

.history-theme {
  margin-bottom: 15px;
}

.theme-label, .content-label {
  font-weight: bold;
  color: #606266;
  width: 100px;
  display: inline-block;
}

.theme-value {
  margin-left: -60px;
  color: #303133;
}

.history-content {
  border-top: 1px dashed #e0e0e0;
  padding-top: 15px;
}

.content-value {
  margin-top: 10px;
  white-space: pre-wrap;
  line-height: 1.8;
  color: #303133;
  padding: 8px 0;
}

.history-dialog .el-dialog__header {
  padding: 20px;
  border-bottom: 1px solid #ebeef5;
  background-color: #f5f7fa;
}

.history-dialog .el-dialog__title {
  font-size: 18px;
  color: #303133;
  font-weight: bold;
}

.history-dialog .el-dialog__body {
  padding: 20px 20px 10px;
}

.timeline-container {
  max-height: 400px;
  overflow-y: auto;
  padding-right: 10px;
  scrollbar-width: thin;
  scrollbar-color: #E4E7ED #F5F7FA;
  margin-top: 15px;
}

.timeline-container::-webkit-scrollbar {
  width: 6px;
}

.timeline-container::-webkit-scrollbar-track {
  background: #F5F7FA;
  border-radius: 3px;
}

.timeline-container::-webkit-scrollbar-thumb {
  background-color: #E4E7ED;
  border-radius: 3px;
}

.timeline-container::-webkit-scrollbar-thumb:hover {
  background-color: #DCDFE6;
}

.reply-history-card {
  margin-bottom: 10px;
  border-left: 2px solid #409EFF;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  transition: all 0.3s;
}

.reply-history-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.reply-history-content {
  padding: 15px;
  background-color: #f9f9f9;
  border-radius: 4px;
  line-height: 1.8;
  white-space: pre-wrap;
  color: #303133;
  font-size: 14px;
}

.reply-history-footer {
  margin-top: 15px;
  padding: 0 15px 10px;
  text-align: right;
  font-size: 12px;
  color: #606266;
  border-top: 1px dashed #ebeef5;
  padding-top: 10px;
}

.reply-user {
  font-size: 13px;
  font-weight: bold;
}

/* 时间线自定义样式 */
.el-timeline-item__timestamp {
  font-size: 13px !important;
  color: #606266;
  font-weight: 500;
}

.el-timeline-item__tail {
  border-left: 2px solid #E4E7ED !important;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .card-footer {
    flex-wrap: wrap;
    justify-content: center;
  }
  
  .card-footer .el-button {
    margin-bottom: 5px;
  }
  
  .reply-actions {
    display: flex;
    flex-direction: column;
  }
  
  .reply-actions .el-button {
    margin-top: 5px;
  }
  
  .history-header {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .history-title {
    margin-bottom: 5px;
    max-width: 100%;
  }
}
</style> 